package com.supercube.wechat.service;

import com.google.gson.Gson;
import com.supercube.common.utils.*;
import com.supercube.wechat.dao.MiniAppApiDao;
import com.supercube.wechat.domain.WeChatUserInfo;
import com.supercube.wechat.properties.WxAuth;
import com.supercube.wechat.utils.TemplateMessageService;
import com.supercube.wechat.utils.WechatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 与微信服务器通信的服务层
 *
 * @author djzhao
 * @date 19/10/02 17:56
 * @email djzhao627@gmail.com
 */
@Service
public class WxService {
    @Autowired
    private WxAuth wxAuth;

    @Autowired
    private MiniAppApiDao miniAppApiDao;

    /**
     * 根据小程序登录返回的code获取openid和session_key
     *
     * @param jsCode 小程序返回的code
     * @return openid和session_key
     */
    public R getWxSession(String jsCode) {
        StringBuilder sb = new StringBuilder();
        sb.append("appid=")
                .append(wxAuth.getAppId())
                .append("&secret=")
                .append(wxAuth.getSecret())
                .append("&js_code=")
                .append(jsCode)
                .append("&grant_type=")
                .append(wxAuth.getGrantType());
        String res = HttpRequest.sendGet(wxAuth.getSessionHost(), sb.toString());
        Map<String, Object> stringObjectMap = JSONUtils.jsonToMap(res);
        String openid = (String) stringObjectMap.get("openid");
        // 不存在openid
        if (openid == null) {
            return R.error(11, "openid无法获取");
        }
        WeChatUserInfo userInfoWithOpenId = miniAppApiDao.getUserInfoWithOpenId(openid);
        // 不是我们的用户
        if (userInfoWithOpenId == null) {
            R err = R.error(12, "用户未注册");
            err.put("openId", openid);
            return err;
        }
        HashMap map = new HashMap();
        map.put("userInfo", userInfoWithOpenId);
        return R.ok(map);
    }

    /**
     * 根据小程序登录返回的code、encryptedData、iv获取openid和session_key并解密encryptedData
     *
     * @param jsCode        小程序返回的code
     * @param encryptedData 小程序返回的encryptedData
     * @param iv            小程序返回的iv
     * @return
     */
    public R getWxSession(String jsCode, String encryptedData, String iv) {
        StringBuilder sb = new StringBuilder();
        // 请求所需参数
        sb.append("appid=")
                .append(wxAuth.getAppId())
                .append("&secret=")
                .append(wxAuth.getSecret())
                .append("&js_code=")
                .append(jsCode)
                .append("&grant_type=")
                .append(wxAuth.getGrantType());
        // 获取openId和session_key
        String res = HttpRequest.sendGet(wxAuth.getSessionHost(), sb.toString());
        Map json = new Gson().fromJson(res, Map.class);
        String openid = (String) json.get("openid");
        // 不存在openid
        if (openid == null) {
            return R.error(11, "openid无法获取");
        }
        String sessionKey = json.get("session_key").toString();
        // 解密encryptedData，获取用户信息
        String userInfo = AesCbcUtil.decrypt(encryptedData, sessionKey, iv, "UTF-8");
        WeChatUserInfo weChatUserInfo = miniAppApiDao.getUserInfoWithOpenId(openid);
        // 不是我们的用户
        if (weChatUserInfo == null) {
            R err = R.error(12, "用户未注册");
            err.put("openId", openid);
            err.put("userInfo", userInfo);
            return err;
        }
        R ok = R.ok();
        ok.put("userInfo", weChatUserInfo);
        return ok;
    }

    /**
     * 使用微信信息注册新用户
     *
     * @param userInfo 微信信息
     * @return 注册的用户信息
     */
    public R registerAsNewUser(WeChatUserInfo userInfo, String jsCode, String encryptedData, String iv) {
        StringBuilder sb = new StringBuilder();
        // 请求所需参数
        sb.append("appid=")
                .append(wxAuth.getAppId())
                .append("&secret=")
                .append(wxAuth.getSecret())
                .append("&js_code=")
                .append(jsCode)
                .append("&grant_type=")
                .append(wxAuth.getGrantType());
        // 获取openId和session_key
        String res = HttpRequest.sendGet(wxAuth.getSessionHost(), sb.toString());
        Map json = new Gson().fromJson(res, Map.class);
        String openid = (String) json.get("openid");
        // 不存在openid
        if (openid == null) {
            return R.error(11, "openid无法获取");
        }
        // 保存openId
        userInfo.setOpenId(openid);
        String sessionKey = json.get("session_key").toString();
        // 解密encryptedData，获取手机号码
        String phoneInfo = AesCbcUtil.decrypt(encryptedData, sessionKey, iv, "UTF-8");
        json = new Gson().fromJson(phoneInfo, Map.class);
        // 保存手机号码信息
        userInfo.setPhoneNumber((String) json.get("phoneNumber"));
        userInfo.setPurePhoneNumber((String) json.get("purePhoneNumber"));
        userInfo.setCountryCode((String) json.get("countryCode"));
        userInfo.setNickName(StringUtils.removeNonBmpUniCodes(userInfo.getNickName()));
        if (miniAppApiDao.insertMember(userInfo) > 0) {
            int i = miniAppApiDao.insertWeChatUser(userInfo);
            if (i > 0) {
                userInfo = miniAppApiDao.getUserInfoWithOpenId(openid);
                R ok = R.ok();
                ok.put("userInfo", userInfo);
                return ok;
            }
        }
        return R.error("暂时无法注册");
    }

    /*public R pushMessage() {
        String token = WechatUtils.getAccess_token(appId, appSecret).getString("access_token");
        TemplateMessageService.sendTemp(appId, token, appSecret, entity.realAmount, tenantEntity.name, memberEntity.wechatOpenId);
    }*/
}